package org.richin.io.fastStream.util;
import java.io.Serializable;

public class ByteArrays
{
  public static final long ONEOVERPHI = 106039L;
  public static final byte[] EMPTY_ARRAY = new byte[0];
  public static final Hash.Strategy<byte[]> HASH_STRATEGY = new ArrayHashStrategy();

  public static byte[] ensureCapacity(byte[] array, int length)
  {
    if (length > array.length) {
      byte[] t = new byte[length];

      System.arraycopy(array, 0, t, 0, array.length);
      return t;
    }
    return array;
  }

  public static byte[] ensureCapacity(byte[] array, int length, int preserve)
  {
    if (length > array.length) {
      byte[] t = new byte[length];

      System.arraycopy(array, 0, t, 0, preserve);
      return t;
    }
    return array;
  }

  public static byte[] grow(byte[] array, int length)
  {
    if (length > array.length) {
      int newLength = (int)Math.min(Math.max(106039L * array.length >>> 16, length), 2147483647L);
      byte[] t = new byte[newLength];

      System.arraycopy(array, 0, t, 0, array.length);
      return t;
    }
    return array;
  }

  public static byte[] grow(byte[] array, int length, int preserve)
  {
    if (length > array.length) {
      int newLength = (int)Math.min(Math.max(106039L * array.length >>> 16, length), 2147483647L);
      byte[] t = new byte[newLength];

      System.arraycopy(array, 0, t, 0, preserve);
      return t;
    }
    return array;
  }

  public static byte[] trim(byte[] array, int length)
  {
    if (length >= array.length) return array;
    byte[] t = (length == 0) ? EMPTY_ARRAY : new byte[length];

    System.arraycopy(array, 0, t, 0, length);
    return t;
  }

  public static byte[] setLength(byte[] array, int length)
  {
    if (length == array.length) return array;
    if (length < array.length) return trim(array, length);
    return ensureCapacity(array, length);
  }

  public static byte[] copy(byte[] array, int offset, int length)
  {
    ensureOffsetLength(array, offset, length);
    byte[] a = (length == 0) ? EMPTY_ARRAY : new byte[length];

    System.arraycopy(array, offset, a, 0, length);
    return a;
  }

  public static byte[] copy(byte[] array)
  {
    return ((byte[])array.clone());
  }

  public static void fill(byte[] array, byte value)
  {
    int i = array.length;
    for (; i-- != 0; array[i] = value);
  }

  public static void fill(byte[] array, int from, int to, byte value)
  {
    ensureFromTo(array, from, to);
    if (from == 0) while (true) { if (to-- == 0) return; array[to] = value; }
    for (int i = from; i < to; ) { array[i] = value; ++i;
    }
  }

	public static boolean equals(byte a1[], byte a2[]) {
		int i = a1.length;
		if (i != a2.length)
			return false;
		while (i-- != 0)
			if (a1[i] != a2[i])
				return false;
		return true;
	}

  public static void ensureFromTo(byte[] a, int from, int to)
  {
   Arrays.ensureFromTo(a.length, from, to);
  }

  public static void ensureOffsetLength(byte[] a, int offset, int length)
  {
    Arrays.ensureOffsetLength(a.length, offset, length); }

  private static final class ArrayHashStrategy implements Hash.Strategy<byte[]>, Serializable {
    public static final long serialVersionUID = -7046029254386353129L;

    public int hashCode(byte[] o) {
      return java.util.Arrays.hashCode(o); }

    public boolean equals(byte[] a, byte[] b) {
      return ByteArrays.equals(a, b);
    }
  }
  public static class Arrays
  {
    public static void ensureFromTo(int arrayLength, int from, int to)
    {
      if (from < 0) throw new ArrayIndexOutOfBoundsException("Start index (" + from + ") is negative");
      if (from > to) throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
      if (to > arrayLength) throw new ArrayIndexOutOfBoundsException("End index (" + to + ") is greater than array length (" + arrayLength + ")");
    }

    public static void ensureOffsetLength(int arrayLength, int offset, int length)
    {
      if (offset < 0) throw new ArrayIndexOutOfBoundsException("Offset (" + offset + ") is negative");
      if (length < 0) throw new IllegalArgumentException("Length (" + length + ") is negative");
      if (offset + length > arrayLength) throw new ArrayIndexOutOfBoundsException("Last index (" + (offset + length) + ") is greater than array length (" + arrayLength + ")");
    }
  }
}

